﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BackTestProvider.cs" company="">
//   
// </copyright>
// <summary>
//   The back test provider.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using Systemathics.FrameWork;
using Systemathics.FrameWork.Interfaces;

namespace Systemathics.Providers
{
    [Serializable]
    [ProviderName(StrategyMode.BackTest)]
    public sealed partial class BackTestProvider : IDataProvider
    {
        private Dictionary<Guid, LastFeed> LastFeeds;
        private readonly string PROVIDER_NAME;
        private bool EmitMarketData;
        private bool EmitTrade;
        private bool isConnected;
        private bool ReadAndEmit;
        public bool StrategyMustBeDisconnected { get; private set; }
        private BackgroundWorker ReadandEmitBackGroundWorker;
        private delegate void FetchDelegate(DateTime begin, DateTime end, Data dt, Guid Id, int? barsize);

        private event EventHandler<FireMessageEventArgs>        _EmitError;
        private event EventHandler<FireMessageEventArgs>        _EmitConnectionStatus;
        private event EventHandler<BarSeries>                   _EmitBarSeries;
        private event EventHandler<TradeSeries>                 _EmitTradeSeries;
        private event EventHandler<QuoteSeries>                 _EmitQuoteSeries;
        private event EventHandler<Trade>                       _EmitNewTrade;
        private event EventHandler<Blotter>                     _EmitNewBlotter;
        private event EventHandler<MarketData>                  _EmitNewMarketData;

        public DateTime? StartBackTestDate { get; set; }
        public DateTime? EndBackTestDate { get; set; }

        public event EventHandler<FireMessageEventArgs> OnBackTestDisconnected;

        #region constructor

        public BackTestProvider()
        {
            var attribute = Attribute.GetCustomAttributes(GetType(), typeof(ProviderName))[0] as ProviderName;
            PROVIDER_NAME = attribute.Name;
            isConnected = false;
            LastFeeds = new Dictionary<Guid, LastFeed>();
            EmitTrade = false;
            StartBackTestDate = null;
            EndBackTestDate = null;
            ReadAndEmit = false;
            StrategyMustBeDisconnected = false;
        }

        #endregion constructor

        #region IConnection 

        string IConnection.Name
        {
            get { return PROVIDER_NAME; }
        }
        bool IConnection.isConnected
        {
            get { return isConnected; }
        }
        void IConnection.Connect()
        {
            if (!isConnected)
            {
                if (StartBackTestDate == null && EndBackTestDate == null)
                {
                    var box = new BackTestProviderForm();
                    if (box.ShowDialog() == DialogResult.OK)
                    {
                        StartBackTestDate = box.FromdateTimePicker.Value.Date;
                        EndBackTestDate = box.TodateTimePicker.Value.Date;
                    }
                }

                if (EndBackTestDate >= StartBackTestDate)
                {
                    isConnected = true;
                    if (_EmitConnectionStatus != null)
                        _EmitConnectionStatus(this,new FireMessageEventArgs(ConnectionStatus.Connected, Time.Now.TimeOfDay));
                }
                else if (EndBackTestDate < StartBackTestDate)
                {
                    isConnected = false;
                    if (_EmitConnectionStatus != null && _EmitError != null)
                    {
                        _EmitError(this, new FireMessageEventArgs("End date must be higher than  Start date.", Time.Now.TimeOfDay));
                        _EmitConnectionStatus(this, new FireMessageEventArgs(ConnectionStatus.Disconnected, Time.Now.TimeOfDay));
                    }
                }
                else
                {
                    isConnected = false;
                    if (_EmitConnectionStatus != null && _EmitError != null)
                    {
                        _EmitError(this, new FireMessageEventArgs("Back Test Dates not present in Data Manager or not valid.", Time.Now.TimeOfDay));
                        _EmitConnectionStatus(this, new FireMessageEventArgs(ConnectionStatus.Disconnected, Time.Now.TimeOfDay));
                    }
                }
            }
        }
        void IConnection.Disconnect()
        {
            if (isConnected)
            {
                isConnected = false;
                if (_EmitConnectionStatus != null && _EmitError != null)
                {
                    _EmitError(this, new FireMessageEventArgs("Connection to BackTest Provider shutdown", Time.Now.TimeOfDay));
                    _EmitConnectionStatus(this, new FireMessageEventArgs(ConnectionStatus.Disconnected, Time.Now.TimeOfDay));
                }
            }
        }
        void IConnection.Suscribe(Instrument instrument)
        {
            if (isConnected)
            {
                DateTime? StartGuidDate = null, EndGuidDate = null;
                GetMinMaxDatesDB(instrument.Id, ref StartGuidDate, ref EndGuidDate);
                if (StartGuidDate != null && EndGuidDate != null)
                {
                    var DBstart = DateTime.Parse(((DateTime)StartGuidDate).ToShortDateString()); 
                    var DBend = DateTime.Parse(((DateTime)EndGuidDate).ToShortDateString());
                    var start = DateTime.Parse((((DateTime)StartBackTestDate)).ToShortDateString());
                    var end = DateTime.Parse(((DateTime)EndBackTestDate).ToShortDateString());

                    if (start >= DBstart && end <= DBend)
                    {
                        if (!LastFeeds.ContainsKey(instrument.Id))
                        {
                            LastFeeds.Add(instrument.Id, new LastFeed(instrument.Id));
                            if (_EmitError != null)
                                _EmitError(this, new FireMessageEventArgs("Suscribing ..." + instrument.StaticData.Name, Time.Now.TimeOfDay));
                        }
                    }
                    else
                    {
                        if (_EmitError != null)
                            _EmitError(this, new FireMessageEventArgs(instrument.StaticData.Name + ": All instruments must be present from start to end date backtest ", Time.Now.TimeOfDay));
                        StrategyMustBeDisconnected = true;
                    }
                }
                else
                {
                    _EmitError(this, new FireMessageEventArgs(instrument.StaticData.Name + " Not present in TickCapture DataBase", Time.Now.TimeOfDay));
                    StrategyMustBeDisconnected = true;
                }
            }
        }
        void IConnection.Unsubscribe(Instrument instrument)
        {
            if (isConnected && !ReadAndEmit)
            {
                if (ReadandEmitBackGroundWorker != null)
                    ReadandEmitBackGroundWorker.CancelAsync();
                LastFeeds.Remove(instrument.Id);
                if (_EmitError != null)
                    _EmitError(this, new FireMessageEventArgs("Unsuscribing ..." + instrument.StaticData.Name, Time.Now.TimeOfDay));
            }
        }

        #endregion IConnection

        #region IDataProvider Members

        void IDataProvider.GetHistoricalData(DateTime Begin, DateTime End, Data dt, Guid Id, int? BarSize)
        {
            FetchDelegate GetHistoryDelegate = Fetch;
            GetHistoryDelegate.Invoke(Begin, End, dt, Id, BarSize);
        }
        void IDataProvider.UpdateInstruments()
        {
        }
        void IDataProvider.UpdateCurrencies()
        {

        }

        event EventHandler<BarSeries> IDataProvider.EmitBarSeries
        {
            add { _EmitBarSeries += value; }
            remove { _EmitBarSeries -= value; }
        }
        event EventHandler<TradeSeries> IDataProvider.EmitTradeSeries
        {
            add { _EmitTradeSeries += value; }
            remove { _EmitTradeSeries -= value; }
        }
        event EventHandler<QuoteSeries> IDataProvider.EmitQuoteSeries
        {
            add { _EmitQuoteSeries += value; }
            remove { _EmitQuoteSeries -= value; }
        }
        event EventHandler<Trade> IDataProvider.EmitNewTrade
        {
            add { _EmitNewTrade += value; }
            remove { _EmitNewTrade -= value; }
        }
        event EventHandler<Blotter> IDataProvider.EmitNewBlotter
        {
            add { _EmitNewBlotter += value; }
            remove { _EmitNewBlotter -= value; }
        }
        event EventHandler<MarketData> IDataProvider.EmitNewMarketData
        {
            add { _EmitNewMarketData += value; }
            remove { _EmitNewMarketData -= value; }
        }
        event EventHandler<FireMessageEventArgs> IConnection.EmitError
        {
            add { _EmitError += value; }
            remove { _EmitError -= value; }
        }
        event EventHandler<FireMessageEventArgs> IConnection.EmitConnectionStatus
        {
            add { _EmitConnectionStatus += value; }
            remove { _EmitConnectionStatus -= value; }
        }

        #endregion

        #region public methods

        public void SetDate(DateTime T1, DateTime T2)
        {
            StartBackTestDate = T1;
            EndBackTestDate = T2;
        }
        public void StartTheBackTest()
        {
            if(StrategyMustBeDisconnected)
            {
                if (OnBackTestDisconnected != null)
                    OnBackTestDisconnected(this, new FireMessageEventArgs(ConnectionStatus.Disconnected, Time.Now.TimeOfDay));
            }
            else if (LastFeeds.Count() > 0)
            {

                LastFeeds = LastFeeds.ToDictionary(u => u.Key, u => new LastFeed(u.Key));
                ReadandEmitBackGroundWorker = new BackgroundWorker();
                ReadandEmitBackGroundWorker.WorkerSupportsCancellation = true;
                ReadandEmitBackGroundWorker.DoWork += ReadandEmitBackGroundWorkerDoWork;
                ReadandEmitBackGroundWorker.RunWorkerAsync();
            }
        }

        #endregion public methods

        #region private methods

        private void GetQuoteFromDataManager(DateTime T1, DateTime T2, Guid guid)
        {
            var sd = new StaticData(guid);
            var qs = new QuoteSeries(sd.Name);
            qs.EmitSeriesError += EmitSeriesError;
            var m_LastFeed = new LastFeed(guid);
            DateTime? StartGuidDate = null, EndGuidDate = null;
            GetMinMaxDatesDB(guid, ref StartGuidDate, ref EndGuidDate);
            if (StartGuidDate != null && EndGuidDate != null)
            {
                if (T1 < StartGuidDate) T1 = (DateTime) StartGuidDate;
                if (T2 > EndGuidDate) T2 = (DateTime) EndGuidDate;

                var b = new List<byte[]>();
                b = GetDATA(guid, T1, T2);

                foreach (var buffer in b)
                {
                    var stream = new MemoryStream(buffer, 0, buffer.Length, false, false);
                    var TempList = new TickCaptures();
                    var formatter = new BinaryFormatter();

                    try
                    {
                        while (stream.Position < stream.Length)
                            TempList.AddRange((TickCaptures) formatter.Deserialize(stream));
                    }
                    catch (Exception ex)
                    {
                        var rem = new RemotingLogClient();
                        rem.Trace(new FireMessageEventArgs(sd.Name + ":  " + ex, Time.Now.TimeOfDay));
                    }

                    foreach (var TickCapture in TempList)
                    {
                        try
                        {
                            switch (TickCapture.Value.TickInfo)
                            {
                                    // Level One
                                case TickInfo.BidSize_1:
                                    m_LastFeed.Blotter[QuoteLevel.One].BidSize = (int) TickCapture.Value.Value;
                                    break;
                                case TickInfo.Bid_1:
                                    m_LastFeed.Blotter[QuoteLevel.One].Bid = TickCapture.Value.Value;
                                    break;
                                case TickInfo.Ask_1:
                                    m_LastFeed.Blotter[QuoteLevel.One].Ask = TickCapture.Value.Value;
                                    break;
                                case TickInfo.AskSize_1:
                                    m_LastFeed.Blotter[QuoteLevel.One].AskSize = (int) TickCapture.Value.Value;
                                    break;
                                default:
                                    break;
                            }

                            if (m_LastFeed.BlotterCheck)
                            {
                                m_LastFeed.Blotter[QuoteLevel.One].Time = TickCapture.Key;
                                qs.Add(m_LastFeed.Blotter[QuoteLevel.One].Clone() as Quote);
                            }
                            else
                                m_LastFeed.CheckBlotter(QuoteLevel.One);
                        }
                        catch (Exception ex)
                        {
                            _EmitError(this, new FireMessageEventArgs(ex, Time.Now.TimeOfDay));
                        }
                    }
                }
            }

// else
            // _EmitError(this, new FireMessageEventArgs(Instrument.GetInstrument(guid).Name + " Not present in TickCapture DataBase", Time.Now.TimeOfDay));
            if (_EmitQuoteSeries != null)
                _EmitQuoteSeries(this, qs);
        }
        private void GetTradeFromDataManager(DateTime T1, DateTime T2, Guid guid)
        {
            var ts = GetTradeFromDataManagerInternal(T1, T2, guid);
            if (_EmitTradeSeries != null)
                _EmitTradeSeries(this, ts);
        }
        private void GetBarFromDataManager(DateTime T1, DateTime T2, Guid guid, int? BarSize)
        {
            var sd = new StaticData(guid);
            var ts = GetTradeFromDataManagerInternal(T1, T2, guid);
            var bs = new BarSeries(sd.Name);
            bs.EmitSeriesError += EmitSeriesError;
            bs = ts.ToBarSeries(BarType.Seconds, (int) BarSize);
            bs.BarType = BarType.Seconds;
            if (_EmitBarSeries != null)
                _EmitBarSeries(this, bs);
        }
        private TradeSeries GetTradeFromDataManagerInternal(DateTime T1, DateTime T2, Guid guid)
        {
            var sd = new StaticData(guid);
            var ts = new TradeSeries(sd.Name);
            ts.EmitSeriesError += EmitSeriesError;
            var m_LastFeed = new LastFeed(guid);
            DateTime? StartGuidDate = null, EndGuidDate = null;
            GetMinMaxDatesDB(guid, ref StartGuidDate, ref EndGuidDate);
            if (StartGuidDate != null && EndGuidDate != null)
            {
                if (T1 < StartGuidDate) T1 = (DateTime) StartGuidDate;
                if (T2 > EndGuidDate) T2 = (DateTime) EndGuidDate;

                var b = new List<byte[]>();
                b = GetDATA(guid, T1, T2);

                foreach (var buffer in b)
                {
                    var stream = new MemoryStream(buffer, 0, buffer.Length, false, false);
                    var tempList = new TickCaptures();
                    var formatter = new BinaryFormatter();

                    try
                    {
                        while (stream.Position < stream.Length)
                            tempList.AddRange((TickCaptures) formatter.Deserialize(stream));
                    }
                    catch (Exception ex)
                    {
                        var rem = new RemotingLogClient();
                        rem.Trace(new FireMessageEventArgs(sd.Name + ":  " + ex, Time.Now.TimeOfDay));
                    }

                    foreach (var tickCapture in tempList)
                    {
                        try
                        {
                            switch (tickCapture.Value.TickInfo)
                            {
                                case TickInfo.LastSize:
                                    m_LastFeed.Trade.Size = (int) tickCapture.Value.Value;
                                    break;
                                case TickInfo.LastTrade:
                                    m_LastFeed.Trade.Price = tickCapture.Value.Value;
                                    break;
                                default:
                                    break;
                            }

                            if (m_LastFeed.TradeCheck)
                            {
                                m_LastFeed.Trade.Time = tickCapture.Key;
                                ts.Add(m_LastFeed.Trade.Clone() as Trade);
                            }
                            else
                                m_LastFeed.CheckTrade();
                        }
                        catch (Exception ex)
                        {
                            _EmitError(this, new FireMessageEventArgs(ex, Time.Now.TimeOfDay));
                        }
                    }
                }
            }
            // else
            // _EmitError(this, new FireMessageEventArgs(Instrument.GetInstrument(guid).Name + " Not present in TickCapture DataBase", Time.Now.TimeOfDay));
            return ts;
        }
        private void EmitSeriesError(object sender, FireMessageEventArgs e)
        {
            _EmitError(this, e);
        }
        private void ReadandEmitBackGroundWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            ReadAndEmitStub();
        }
        private void Fetch(DateTime Begin, DateTime End, Data dt, Guid Id, int? BarSize)
        {
            if (End >= Begin)
            {
                switch (dt)
                {
                    case Data.Bar:
                        // BarSize is in seconds
                        GetBarFromDataManager(Begin, End, Id, BarSize);
                        break;
                    case Data.Quote:
                        GetQuoteFromDataManager(Begin, End, Id);
                        break;
                    case Data.Trade:
                        GetTradeFromDataManager(Begin, End, Id);
                        break;
                    default:
                        break;
                }
            }
        }
        private void ReadAndEmitStub()
        {
            ReadAndEmit = true;
            var readAndEmitDate = (DateTime) StartBackTestDate;
            while (readAndEmitDate <= (DateTime) EndBackTestDate)
            {
                var TheBigOne = new SortedDictionary<DateTime, TickCaptureGuid>();

                foreach (Guid Guid in LastFeeds.Keys)
                {
                    List<byte[]> buffer = GetDATA(Guid, readAndEmitDate, readAndEmitDate);
                    var stream = new MemoryStream(buffer.First(), 0, buffer.First().Length, false, false);
                    var tempList = new TickCaptures();
                    var formatter = new BinaryFormatter();

                    try
                    {
                        while (stream.Position < stream.Length)
                            tempList.AddRange((TickCaptures) formatter.Deserialize(stream));

                        AddRange(Guid, tempList, ref TheBigOne);
                        tempList.Clear();
                    }
                    catch (Exception ex)
                    {
                        var rem = new RemotingLogClient();
                        rem.Trace(new FireMessageEventArgs(Guid + ":  " + ex, Time.Now.TimeOfDay));
                    }
                }

                ReadAndEmitTheBigOne(TheBigOne);
                readAndEmitDate = readAndEmitDate.AddDays(1);
            }

            if (OnBackTestDisconnected != null)
                OnBackTestDisconnected(this, new FireMessageEventArgs(ConnectionStatus.Disconnected, Time.Now.TimeOfDay));
            ReadAndEmit = false;
        }
        private void ReadAndEmitTheBigOne(SortedDictionary<DateTime, TickCaptureGuid> TheBigOne)
        {
            try
            {
                QuoteLevel level = QuoteLevel.Five;
                foreach (var kvp in TheBigOne)
                {
                    EmitTrade = false;
                    EmitMarketData = false;

                    switch (kvp.Value.tc.TickInfo)
                    {
                        case TickInfo.Ask_1:
                            level = QuoteLevel.One;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.Ask_1;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.One].Ask = kvp.Value.tc.Value;
                            break;
                        case TickInfo.Ask_2:
                            level = QuoteLevel.Two;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.Ask_2;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Two].Ask = kvp.Value.tc.Value;
                            break;
                        case TickInfo.Ask_3:
                            level = QuoteLevel.Three;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.Ask_3;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Three].Ask = kvp.Value.tc.Value;
                            break;
                        case TickInfo.Ask_4:
                            level = QuoteLevel.Four;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.Ask_4;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Four].Ask = kvp.Value.tc.Value;
                            break;
                        case TickInfo.Ask_5:
                            level = QuoteLevel.Five;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.Ask_5;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Five].Ask = kvp.Value.tc.Value;
                            break;

                            // AskSize
                        case TickInfo.AskSize_1:
                            level = QuoteLevel.One;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.AskSize_1;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.One].AskSize = (int) kvp.Value.tc.Value;
                            break;
                        case TickInfo.AskSize_2:
                            level = QuoteLevel.Two;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.AskSize_2;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Two].AskSize = (int) kvp.Value.tc.Value;
                            break;
                        case TickInfo.AskSize_3:
                            level = QuoteLevel.Three;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.AskSize_3;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Three].AskSize = (int) kvp.Value.tc.Value;
                            break;
                        case TickInfo.AskSize_4:
                            level = QuoteLevel.Four;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.AskSize_4;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Four].AskSize = (int) kvp.Value.tc.Value;
                            break;
                        case TickInfo.AskSize_5:
                            level = QuoteLevel.Five;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.AskSize_5;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Five].AskSize = (int) kvp.Value.tc.Value;
                            break;

                            // Bid
                        case TickInfo.Bid_1:
                            level = QuoteLevel.One;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.Bid_1;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.One].Bid = kvp.Value.tc.Value;
                            break;
                        case TickInfo.Bid_2:
                            level = QuoteLevel.Two;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.Bid_2;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Two].Bid = kvp.Value.tc.Value;
                            break;
                        case TickInfo.Bid_3:
                            level = QuoteLevel.Three;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.Bid_3;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Three].Bid = kvp.Value.tc.Value;
                            break;
                        case TickInfo.Bid_4:
                            level = QuoteLevel.Four;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.Bid_4;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Four].Bid = kvp.Value.tc.Value;
                            break;
                        case TickInfo.Bid_5:
                            level = QuoteLevel.Five;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.Bid_5;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Five].Bid = kvp.Value.tc.Value;
                            break;

                            // BidSize
                        case TickInfo.BidSize_1:
                            level = QuoteLevel.One;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.BidSize_1;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.One].BidSize = (int) kvp.Value.tc.Value;
                            break;
                        case TickInfo.BidSize_2:
                            level = QuoteLevel.Two;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.BidSize_2;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Two].BidSize = (int) kvp.Value.tc.Value;
                            break;
                        case TickInfo.BidSize_3:
                            level = QuoteLevel.Three;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.BidSize_3;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Three].BidSize = (int) kvp.Value.tc.Value;
                            break;
                        case TickInfo.BidSize_4:
                            level = QuoteLevel.Four;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.BidSize_4;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Four].BidSize = (int) kvp.Value.tc.Value;
                            break;
                        case TickInfo.BidSize_5:
                            level = QuoteLevel.Five;
                            LastFeeds[kvp.Value.Guid].Blotter.TickInfo = TickInfo.BidSize_5;
                            LastFeeds[kvp.Value.Guid].Blotter[QuoteLevel.Five].BidSize = (int) kvp.Value.tc.Value;
                            break;

                            // Trade
                        case TickInfo.LastSize:
                            LastFeeds[kvp.Value.Guid].Trade.Size = (int) kvp.Value.tc.Value;
                            EmitTrade = true;
                            break;
                        case TickInfo.LastTrade:
                            LastFeeds[kvp.Value.Guid].Trade.Price = kvp.Value.tc.Value;
                            EmitTrade = true;
                            break;

                            // Market Data
                        case TickInfo.Open:
                            LastFeeds[kvp.Value.Guid].Marketdata.Open = kvp.Value.tc.Value;
                            EmitMarketData = true;
                            break;
                        case TickInfo.Close:
                            LastFeeds[kvp.Value.Guid].Marketdata.Close = kvp.Value.tc.Value;
                            EmitMarketData = true;
                            break;
                        default:
                            break;
                    }

                    if (EmitTrade)
                    {
                        if (LastFeeds[kvp.Value.Guid].TradeCheck)
                        {
                            LastFeeds[kvp.Value.Guid].Trade.Time = kvp.Key;
                            _EmitNewTrade(this, LastFeeds[kvp.Value.Guid].Trade);

                            if (LastFeeds[kvp.Value.Guid].Trade.Price > LastFeeds[kvp.Value.Guid].Marketdata.High)
                            {
                                LastFeeds[kvp.Value.Guid].Marketdata.High = LastFeeds[kvp.Value.Guid].Trade.Price;
                                EmitMarketData = true;
                            }

                            if (LastFeeds[kvp.Value.Guid].Trade.Price < LastFeeds[kvp.Value.Guid].Marketdata.Low)
                            {
                                LastFeeds[kvp.Value.Guid].Marketdata.Low = LastFeeds[kvp.Value.Guid].Trade.Price;
                                EmitMarketData = true;
                            }
                        }
                        else
                            LastFeeds[kvp.Value.Guid].CheckTrade();
                    }
                    else if (EmitMarketData)
                    {
                        if (LastFeeds[kvp.Value.Guid].MarketdataCheck)
                            _EmitNewMarketData(this, LastFeeds[kvp.Value.Guid].Marketdata);
                        else
                            LastFeeds[kvp.Value.Guid].CheckMarketData();
                    }
                    else
                    {
                        if (LastFeeds[kvp.Value.Guid].BlotterCheck)
                        {
                            LastFeeds[kvp.Value.Guid].Blotter[level].Time = kvp.Key;
                            _EmitNewBlotter(this, LastFeeds[kvp.Value.Guid].Blotter);
                        }
                        else
                            LastFeeds[kvp.Value.Guid].CheckBlotter(QuoteLevel.One);
                    }
                }
            }
            catch (Exception e)
            {

            }
        }

        #endregion private methods

        void IDisposable.Dispose()
        {
            if (ReadandEmitBackGroundWorker != null)
                ReadandEmitBackGroundWorker.Dispose();
        }
    }
}